﻿using System;
using System.Linq;
using System.Web.Mvc;
using System.Collections.Generic;
using Caramel.Entities;

namespace Caramel.Web.Mvc
{
	public static class EnumerableExtensions
	{
		public static IEnumerable<SelectListItem> ToSelectListItemList<T>(this IEnumerable<T> source, Func<T, object> text, Func<T, object> value)
		{
			return
				source.
					ToSelectListItemList(
						text,
						value,
						i => false
					);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList<T>(this IEnumerable<T> source, Func<T, object> text, Func<T, object> value, string defaultOption)
		{
			return
				new[]
				{
					new SelectListItem()
					{
						Text = defaultOption
					}
				}.
				Union(
					source.
						ToSelectListItemList(
							text,
							value,
							i => false
						)
				);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList<T>(this IEnumerable<T> source, Func<T, object> text, Func<T, object> value, Func<T, bool> selected)
		{
			return
				source.
					ToSelectListItemList(
						text,
						value,
						(e, i) => selected(e)
					);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList<T>(this IEnumerable<T> source, Func<T, object> text, Func<T, object> value, Func<T, bool> selected, string defaultOption)
		{
			return
				new[]
				{
					new SelectListItem()
					{
						Text = defaultOption
					}
				}.
				Union(
					source.
						ToSelectListItemList(
							text,
							value,
							(e, i) => selected(e)
						)
				);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList<T>(this IEnumerable<T> source, Func<T, object> text, Func<T, object> value, Func<T, int, bool> selected)
		{
			return
				source.
					Select(
						(e, i) =>
						new SelectListItem()
						{
							Text = text(e).ToString(),
							Value = value(e).ToString(),
							Selected = selected(e, i)
						}
					);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList<T>(this IEnumerable<T> source, Func<T, object> text, Func<T, object> value, Func<T, int, bool> selected, string defaultOption)
		{
			return
				new[]
				{
					new SelectListItem()
					{
						Text = defaultOption
					}
				}.
				Union(
					source.
						Select(
							(e, i) =>
							new SelectListItem()
							{
								Text = text(e).ToString(),
								Value = value(e).ToString(),
								Selected = selected(e, i)
							}
						)
				);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList(this IEnumerable<NamedEntity<Guid?>> source)
		{
			return
				source.
					ToSelectListItemList(e => false);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList(this IEnumerable<NamedEntity<Guid?>> source, string defaultOption)
		{
			return
				source.
					ToSelectListItemList(
						e => false,
						defaultOption
					);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList(this IEnumerable<NamedEntity<Guid?>> source, Func<NamedEntity<Guid?>, bool> selected)
		{
			return
				source.
					ToSelectListItemList(
						(e, i) => selected(e)
					);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList(this IEnumerable<NamedEntity<Guid?>> source, Func<NamedEntity<Guid?>, bool> selected, string defaultOption)
		{
			return
				source.
					ToSelectListItemList(
						(e, i) => selected(e),
						defaultOption
					);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList(this IEnumerable<NamedEntity<Guid?>> source, Func<NamedEntity<Guid?>, int, bool> selected)
		{
			return
				source.
					ToSelectListItemList(
						e => e.Name,
						e => e.ID.ToString(),
						selected
					);
		}

		public static IEnumerable<SelectListItem> ToSelectListItemList(this IEnumerable<NamedEntity<Guid?>> source, Func<NamedEntity<Guid?>, int, bool> selected, string defaultOption)
		{
			return
				source.
					ToSelectListItemList(
						e => e.Name,
						e => e.ID.ToString(),
						selected,
						defaultOption
					);
		}
	}
}
